package kRender;

import kGeom.*;
import kMesh.kMesh;
import processing.core.*;

public class kSpace extends kElementBuffer {

	public Camera cam;
	public PApplet pA;
	
	private static final float[] defaultBackgroundColor = new float[] {110,110,140};	
	private float[] backgroundColor;
	public void backgroundColor(float r, float g, float b) {
		backgroundColor = new float[] {r,g,b};
	}
	public float[] backgroundColor() {
		return backgroundColor;
	}
	
	public static final float clip = 10.0f;
	
	// graphic defaults
	public static int ptDrawSize = 3;
	public int mshDrawStyle = 0;
	public int vecFieldDrawStyle = 0;
	public int triDrawStyle = 0;
	
	public kSpace( PApplet parent ) {
		super();
		System.out.println(kUtil.brandingString);
		pA = parent;
		cam = new Camera(0,0,120);
		//cam.roll(3.14f);
		setCameraAspect();
		backgroundColor = defaultBackgroundColor;
	}
	
	public void setCameraAspect(){
		cam.aspect = (float) pA.width/(float) pA.height;
	}
	

	public void mouseDragged() {
		char action = 'x';
		
		if ((pA.keyPressed) && (pA.key==PApplet.CODED)){
			if (pA.keyCode == PApplet.SHIFT){
				action = 'p';
			} else if ((pA.keyCode == PApplet.CONTROL)||(pA.keyCode == 157)){
				action = 'z';
			}
		} else {
			action = 'r';
		}
		
        switch (action) {
            case 'r':  
            	//PApplet.println("rotating");
    			cam.tumble(PApplet.radians(pA.pmouseX - pA.mouseX), PApplet.radians(pA.pmouseY - pA.mouseY));
            	break;
            case 'p':  
            	//PApplet.println("panning");
				cam.truck((pA.mouseX - pA.pmouseX) / -4.0f);
				cam.boom((pA.mouseY - pA.pmouseY) / -4.0f);
            	break;
            case 'z':  
            	//PApplet.println("zooming");
            	cam.dolly((pA.mouseY - pA.pmouseY) / 1.0f);
            	break;
            default: 
            	break;
        }
		
	}

	
	public void render() {
		pA.background(backgroundColor[0],backgroundColor[1],backgroundColor[2]);
		PGraphics3D pG = (PGraphics3D) pA.g;
		
		pG.pushMatrix();
		cam.feed(pA);
		
		drawOriginIcon();
		
		for (int n = 0; n < elements.length; n++) {
			Class c = elements[n].getClass();
			
			if (c == kVec.class) {
				DrawUtil.drawVec((kVec) elements[n], ptDrawSize, pG);
			} else if (c == kLine.class){
				DrawUtil.drawLine((kLine) elements[n], pG);
			} else if (c == kPolyline.class){
				DrawUtil.drawPolyline((kPolyline) elements[n], pG);	
			} else if (c == kRange.class){
				DrawUtil.drawRange((kRange) elements[n], pG);
			} else if (c == kPointCloud.class){
				DrawUtil.drawPointCloud((kPointCloud) elements[n], pG, ptDrawSize);
			} else if (c == kMesh.class){
				DrawUtil.drawMesh((kMesh) elements[n], pG , mshDrawStyle);
			} else if (c == kVecField.class){
				DrawUtil.drawVecField((kVecField) elements[n], pG , vecFieldDrawStyle);				
			} else if (c == kTri.class){
					DrawUtil.drawTriangle((kTri) elements[n], pG , triDrawStyle);
				} else {
				// ERROR
			}
			
		}
		pG.popMatrix();
	}
	
	public void init(){
		this.clear();
	}
	

	private void drawOriginIcon() {
		pA.noFill();
		
		pA.stroke(255,0,0);
		pA.line(0,0,0,10,0,0);
		
		pA.stroke(0,255,0);
		pA.line(0,0,0,0,10,0);
		
		pA.stroke(0,0,255);
		pA.line(0,0,0,0,0,10);
	}
	
	private kRange boundingBox(){
		//TODO: element range doesn't work
		return range;
	}
	
	
	private void refitCamera(){
		//TODO: element range doesn't work
		
		kVec camPos = new kVec( cam.cameraX, cam.cameraY, cam.cameraZ );
		kVec tarPos =  new kVec(cam.targetX, cam.targetY, cam.targetZ );
		kVec camVec = kVec.minus(tarPos, camPos);
		
		camVec.resize( (float) Math.sqrt(range.area())/3 );
		
		kVec tar = range.center();
		kVec pos = kVec.minus(tar,camVec);
		
		
		cam.aim(tar.x,tar.y,tar.z);
		cam.jump(pos.x,pos.y,pos.z );
		
	}
	

	

	
}
